package org.jeecg.modules.htxincailiao.account.domain.bo;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.jeecg.modules.htxincailiao.account.constant.HTAccountConstant.*;

@Data
public class LimitSignInAttempts {
private static final Logger logger = LoggerFactory.getLogger(LimitSignInAttempts.class);
    private boolean isLocked = false;

    private Result<JSONObject> result;


    public static LimitSignInAttempts CheckFailedLock(RedisUtil redisUtil, String phoneNumber, String username, Result<JSONObject> result) {
        String signInFailedLockKey = GetSignInFailedLockKey(phoneNumber, username);
        boolean isLocked = GetLockState(redisUtil, phoneNumber, username, result);
        long seconds = redisUtil.getExpire(signInFailedLockKey);
//        System.out.printf("\n\n\n getExpire %s \n\n\n", JSONObject.toJSONString(seconds));
        if (isLocked) {
            long minutes = (long) Math.floor((double) (seconds / 60));
            long remainingSeconds = (seconds - minutes * 60);
            result.error500("账户已锁定" + minutes + "分" + remainingSeconds + "秒" + "后解锁");
        }


        if (seconds <= 0) {
//            redisUtil.del(signInFailedLockKey);
//            redisUtil.set(signInFailedLockKey, false, 0);
//            ResetAttemptsInfo(redisUtil, phoneNumber, username);
        }

        LimitSignInAttempts attempts = new LimitSignInAttempts();
        attempts.setLocked(isLocked);
        attempts.setResult(result);

        return attempts;
    }

    private static boolean GetLockState(RedisUtil redisUtil, String phoneNumber, String username, Result<JSONObject> result) {
        String signInFailedLockKey = GetSignInFailedLockKey(phoneNumber, username);
        Object isLockedObject = redisUtil.get(signInFailedLockKey);
        boolean isLocked = false;
        if (oConvertUtils.isEmpty(isLockedObject)) {
            isLockedObject = redisUtil.get(signInFailedLockKey);
        }

        if (oConvertUtils.isNotEmpty(isLockedObject)) {
            isLocked = (boolean) isLockedObject;
        }

        return isLocked;
    }

    public static LimitSignInAttempts HandleFailedAttempts(RedisUtil redisUtil, String phoneNumber, String username, Result<JSONObject> result) {
        String signInFailedLockKey = GetSignInFailedLockKey(phoneNumber, username);
        // 获取失败次数
        String signInFailedAttemptCountKey = GetSignInFailedAttemptCountKey(phoneNumber, username);
        Object signInFailedAttemptCountObject = redisUtil.get(signInFailedAttemptCountKey);
        int signInFailedAttemptCount = 1;
        boolean isLocked = false;

        //第一次错误登录
        if (oConvertUtils.isEmpty(signInFailedAttemptCountObject)) {
            redisUtil.set(signInFailedAttemptCountKey, signInFailedAttemptCount);
        } else {
            signInFailedAttemptCount = (int) signInFailedAttemptCountObject;
        }

        System.out.printf(" Sign In Failed Attempt Count %s \n", JSONObject.toJSONString(signInFailedAttemptCount));

//        if (signInFailedAttemptCount > 1 || signInFailedAttemptCount <= SIGN_IN_MAX_FAILED_ATTEMPTS) {
//
//        }

        if (signInFailedAttemptCount > SIGN_IN_MAX_FAILED_ATTEMPTS) {
            redisUtil.set(signInFailedLockKey, true, SIGN_IN_FAILED_LOCK_TIME_DURATION);
            redisUtil.set(signInFailedAttemptCountKey, signInFailedAttemptCount, SIGN_IN_FAILED_LOCK_TIME_DURATION);

            isLocked = true;

            String message = "连续" + SIGN_IN_MAX_FAILED_ATTEMPTS + "次密码或验证码错误，"
                    + "账户锁定" + SIGN_IN_FAILED_LOCK_TIME_DURATION / 60 + "分钟";
            result.error500(message);
        } else {
            signInFailedAttemptCount++;
            redisUtil.set(signInFailedAttemptCountKey, signInFailedAttemptCount);
        }

        LimitSignInAttempts attempts = new LimitSignInAttempts();
        attempts.setLocked(isLocked);
        attempts.setResult(result);

        return attempts;
    }

    private static String GetSignInFailedAttemptCountKey(String phoneNumber, String username) {
        String signInFailedAttemptCountKey = null;
        if (oConvertUtils.isNotEmpty(phoneNumber)) {
            signInFailedAttemptCountKey = SIGN_IN_FAILED_ATTEMPT_COUNT_KEY_PREFIX + phoneNumber;
        }

        if (oConvertUtils.isNotEmpty(username)) {
            signInFailedAttemptCountKey = SIGN_IN_FAILED_ATTEMPT_COUNT_KEY_PREFIX + username;
        }

        return signInFailedAttemptCountKey;
    }

    private static String GetSignInFailedLockKey(String phoneNumber, String username) {
        String signInFailedLockKey = null;
        if (oConvertUtils.isNotEmpty(phoneNumber)) {
            signInFailedLockKey = SIGN_IN_FAILED_LOCK_KEY_PREFIX + phoneNumber;
        }

        if (oConvertUtils.isNotEmpty(username)) {
            signInFailedLockKey = SIGN_IN_FAILED_LOCK_KEY_PREFIX + username;
        }

        return signInFailedLockKey;
    }

    public static void ResetAttemptsInfo(RedisUtil redisUtil, String phoneNumber, String username) {
        String signInFailedLockKey = GetSignInFailedLockKey(phoneNumber, username);
        String signInFailedAttemptCountKey = GetSignInFailedAttemptCountKey(phoneNumber, username);

        redisUtil.del(signInFailedLockKey);
        redisUtil.del(signInFailedAttemptCountKey);
    }
}
